package eom.example.local.utils;

import bom.example.common.utils.PathUtils;
import bom.example.common.utils.ReflectUtils;
import bom.example.common.utils.TxtUtils;
import com.alibaba.fastjson.JSON;


import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author X.I.O
 * @title: ObjectUtils
 * @projectName spring-boot-local
 * @description: TODO
 * @date 2021/11/9 15:52
 *
 * 对象数据处理
 */
public class ObjectUtils {

    private static final String OBJ_FILE="obj";




    private static File getFile(){
        File file= PathUtils.getPathByName(OBJ_FILE);
        return file;
    }

    private static File getFileByName(String name){
        File file=getFile();
        String path=file.getPath()+File.separator+name;
        File file1 = new File(path);
        if(!file1.exists()){
            file1.mkdirs();
        }
        File file2=new File(file1.getPath()+File.separator+name);
        return file2;
    }

    private static <T> void writeList(List<T> tList,Class<T> cls){
        //放入缓存
        CacheUtils.put(cls,tList);
        String objName=cls.getName();
        String str= JSON.toJSONString(tList);
        File file=getFileByName(objName);
        TxtUtils.writeTxtCoverFile(file,str);
    }


    /**
     * 储存多个
     * @param tList
     * @param cls
     * @param <T>
     */
    public static<T> void saveList(List<T> tList,Class<T> cls){
        List<T> ts=getList(cls);
        ts.addAll(tList);
        writeList(ts,cls);
    }

    /**
     * 通过id自增保存
     * @param t
     * @param <T>
     * @return
     */
    public static <T> int autoNumSaveObjById(T t){
        Class<T> cls=(Class<T>) t.getClass();
        return autoNumSaveObj("id",t,cls);
    }

    /**
     * 通过id批量自增
     * @param tList
     * @param <T>
     */
    public static <T> void autoNumSaveListById(List<T> tList){
        autoNumSaveListByFieldName(tList,"id");
    }

    /**
     * 批量自动递增
     * @param tList
     * @param fieldName
     * @param <T>
     */
    public static <T> void autoNumSaveListByFieldName(List<T> tList,String fieldName){
        if(tList==null || tList.size()==0){
            return;
        }
        T objField=tList.get(0);
        Class<T> tClass= ReflectUtils.getClass(objField);
        Field field=ReflectUtils.getFieldByName(objField,fieldName);
        field.setAccessible(true);
        List<T> ts=getList(tClass);
        int index=0;
        try {
            for (int i = 0; i < tList.size(); i++) {
                T obj=tList.get(i);
                if(i==0){
                    index=autoNumCommon(ts,field,obj,tClass);
                }else {
                    index++;
                    field.set(obj,index);
                }
                ts.add(obj);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        writeList(ts,tClass);
    }



    /**
     * 模糊搜索所有属性并分页
     * @param cls
     * @param keyword
     * @param page
     * @param size
     * @param <T>
     * @return
     */
    public static <T> IPage<T> searchPageByKeyword(Class<T> cls,String keyword,int page,int size){
        List<T> tList=getList(cls);
        IPage<T> page1=ListUtils.getLikeListByKeyWord(tList,keyword,page,size);
        return page1;
    }

    /**
     * 根据属性自增
     * @param field
     * @param t
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> int autoNumSaveObj(String field,T t,Class<T> cls){
        List<T> ts=getList(cls);
        Field field1=ReflectUtils.getFieldByName(t,field);
        int num=0;
        try {
            num=autoNumCommon(ts,field1,t,cls);
            ts.add(t);
        }catch (Exception e){
            e.printStackTrace();
        }
        writeList(ts,cls);
        return num;
    }

    private static <T> int autoNumCommon(List<T> ts,Field field,T t,Class<T> cls) throws Exception{
        int num=0;
        int size=0;
        if(field!=null){
            if(ts.size()!=0){
                size=ts.size()-1;
                T t1=ts.get(size);
                Object t1_var=ReflectUtils.getObjectByField(t1,field);
                num=(int)t1_var+1;
            }
            ReflectUtils.setObjectByField(field,t,num);
        }
        return num;
    }




    public static <T> void saveObj(T t){
        Class<T> cls=(Class<T>) t.getClass();
        saveObj(t,cls);
    }

    public static <T> void deleteById(Class<T> cls,Object value){
        List<T> ts=getList(cls);
        if(ts!=null && ts.size()!=0){
            List<T> tList=ListUtils.filterListByField(ts,"id",value);
            writeList(tList,cls);
        }
    }



    /**
     * 通过id更新对象
     * @param t
     * @param <T>
     */
    public static <T> void updateById(T t){
        Class<T> cls=ReflectUtils.getClass(t);
        try {
            Object id=ReflectUtils.getObjectByFieldName("id",t);
            List<T> ts=getList(cls);
            Integer index=ListUtils.getIndexById(ts,"id",id);
            if(index!=null){
                ts.set(index,t);
            }
            writeList(ts,cls);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static <T> T getById(Class<T> cls,Object value){
        List<T> ts=getList(cls);
        return ListUtils.getObjectByFieldName(ts,"id",value);
    }


    /**
     * 存储单个
     * @param t
     * @param cls
     * @param <T>
     */
    public static <T> void  saveObj(T t,Class<T> cls){
        List<T> ts=getList(cls);
        ts.add(t);
        writeList(ts,cls);
    }

    /**
     * 用新的list<T> 覆盖旧数据
     * @param <T>
     */
    public static <T> void coverList(List<T> ts,Class<T> cls){
        writeList(ts,cls);
    }


    public static <T> List<T> getList(Class<T> cls){
        List<T> tList=null;
        tList=CacheUtils.getList(cls);
        if(tList!=null){
            return tList;
        }
        String objName=cls.getName();
        System.out.println(objName+"走缓存了哦");
        File file=getFileByName(objName);
        String str= TxtUtils.getTextString(file);
        if(!"".equals(str)){
            tList= JSON.parseArray(str,cls);
        }else {
            tList=new ArrayList<>();
        }
        return tList;
    }



}
